package com.itheima.stock.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.stock.entity.*;
import com.itheima.stock.mapper.*;
import com.itheima.stock.properties.MarketProperties;
import com.itheima.stock.response.PageResult;
import com.itheima.stock.service.StockService;
import com.itheima.stock.util.DateTimeUtil;
import com.itheima.stock.vo.*;
import com.xxl.job.core.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.MathContext;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * @文件名: StockServiceImpl
 * @作者: DX
 * @创建日期: 2025/10/23
 * @描述:
 */
@Service
public class StockServiceImpl implements StockService {

    private final StockBusinessMapper stockBusinessMapper;

    public StockServiceImpl(StockBusinessMapper stockBusinessMapper) {
        this.stockBusinessMapper = stockBusinessMapper;
    }

    @Autowired
    private MarketProperties marketProperties;
    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;
    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;
    @Autowired
    private StockMarketLogPriceMapper stockMarketLogPriceMapper;
    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;

    @Override
    public UpDownVO<OptionVO> upDownCount() {

        LocalDateTime last1 = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());

        String curTimeStr="20220106142500";
        //对应开盘日期 mock_data
        String openTimeStr="20220106092500";

        List<OptionVO> upList = stockRtInfoMapper.selectUpOrDown(curTimeStr, openTimeStr,true);

        List<OptionVO> downList = stockRtInfoMapper.selectUpOrDown(curTimeStr, openTimeStr,false);

        upList = upList.stream().map(option -> {
            if (option.getTime() != null) {
                try {
                    LocalDateTime parsedTime = LocalDateTime.parse(option.getTime(),
                            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    String formattedTime = parsedTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

                    return OptionVO.builder()
                            .count(option.getCount())
                            .time(formattedTime)
                            .build();
                } catch (Exception e) {
                    return option;
                }
            }
            return option;
        }).toList();

        downList = downList.stream().map(option -> {
            if (option.getTime() != null) {
                try {
                    LocalDateTime parsedTime = LocalDateTime.parse(option.getTime(),
                            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                    String formattedTime = parsedTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

                    return OptionVO.builder()
                            .count(option.getCount())
                            .time(formattedTime)
                            .build();
                } catch (Exception e) {
                    return option;
                }
            }
            return option;
        }).toList();

        return UpDownVO.<OptionVO>builder()
                .upList(upList)
                .downList(downList)
                .build();
    }

    @Override
    public PageResult<MoreVO> stockPage(Integer page, Integer pageSize) {

        LocalDateTime last1 = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());

        final LocalDateTime last = LocalDateTime.parse("2021-12-30 09:32:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));



        Page<MoreVO> resylt = PageHelper.startPage(page, pageSize).doSelectPage(() -> {
            List<MoreVO> moreVOList = stockRtInfoMapper.selectMore(last);
        });

        return PageResult.<MoreVO>builder()
                .size(resylt.size())
                .totalRows(resylt.getTotal())
                .pageNum(resylt.getPageNum())
                .totalPages(resylt.getPages())
                .pageSize(resylt.getPageSize())
                .rows(resylt.getResult())
                .build();
     }

    @Override
    public List<StockUpdownDomainVO> stockIncreaseLimit() {

        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());

        last = LocalDateTime.parse("2021-12-30 09:32:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        List<StockRtInfo> stockUpdownDomainList = stockRtInfoMapper.selectByDateTime(last);

        List<StockUpdownDomainVO> result = new ArrayList<>();
        stockUpdownDomainList.stream().forEach(stock -> {
            StockUpdownDomainVO build = StockUpdownDomainVO.builder()
                    .code(stock.getStockCode())
                    .name(stock.getStockName())
                    .curDate(stock.getCurTime().toLocalDate().format(DateTimeFormatter.ofPattern("yyyyMMdd")))
                    .tradePrice(stock.getCurPrice())
                    .tradeVol(stock.getTradeVolume())
                    .tradeAmt(stock.getTradeAmount())
                    .preClosePrice(stock.getPreClosePrice())
                    .increase(stock.getCurPrice().subtract(stock.getPreClosePrice()).divide(stock.getPreClosePrice(), new MathContext(6)).multiply(new BigDecimal("1.0")))
                    .upDown(stock.getCurPrice().subtract(stock.getPreClosePrice()))
                    .amplitude(stock.getMaxPrice().subtract(stock.getMinPrice()).divide(stock.getPreClosePrice(), new MathContext(6)).multiply(new BigDecimal("1.0")))
                    .build();
            result.add(build);
        });

        return result.stream().sorted((o1, o2) -> o2.getIncrease().compareTo(o1.getIncrease())).limit(10).toList();

    }

    @Override
    public List<StockBlockRtInfoVO> sectorAllLimit() {

        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());

        last = LocalDateTime.parse("2021-12-21 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        LocalDateTime openDate = DateTimeUtil.getOpenDate(last);
        LocalDateTime end = DateTimeUtil.getCloseDate(last);

        List<StockBlockRtInfo> rtInfoList = stockBlockRtInfoMapper.selectStockBlockAll(openDate, end);

        return rtInfoList.stream().map(info ->
                StockBlockRtInfoVO.builder()
                        .code(info.getLabel())
                        .name(info.getBlockName())
                        .curDate(info.getCurTime().toLocalDate().toString())
                        .companyNum(info.getCompanyNum())
                        .tradeAmt(info.getTradeAmount())
                        .tradeVol(info.getTradeVolume())
                        .avgPrice(info.getAvgPrice())
                        .updownRate(info.getUpdownRate())
                        .build()
        ).toList();
    }

    @Override
    public List<MarketIndexVO> innerIndexAll() {

        List<String> ids = marketProperties.getInner();

        //股票交易时间【9：30-11：30 13：00-15：00】（除法定节假日外的工作日）
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());

        String mockDate = "20211226105600";
        last = LocalDateTime.parse(mockDate, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

        List<StockMarketIndexInfo> stockMarketIndexInfoList = stockMarketIndexInfoMapper.selectByIdsAndDateTime(ids, last);

        LocalDate localDate = last.toLocalDate();
        List<StockMarketLogPrice> marketLogPriceList = stockMarketLogPriceMapper.selectByIdsAndDateTime(ids, localDate);

        return stockMarketIndexInfoList.stream().map(infpo -> {
            MarketIndexVO vo = MarketIndexVO.builder()
                    .code(infpo.getMarkId())
                    .name(infpo.getMarkName())
                    .curDate(infpo.getCurTime().toLocalDate().toString())
                    .tradeAmt(infpo.getTradeAccount())
                    .tradeVol(infpo.getTradeVolume())
                    .tradePrice(infpo.getCurrentPrice())
                    .upDown(infpo.getUpdownRate())
                    .build();
            boolean found = false;
            for (StockMarketLogPrice marketLogPrice : marketLogPriceList) {
                if (marketLogPrice.getMarketCode().equals(infpo.getMarkId())) {
                    vo.setOpenPrice(marketLogPrice.getOpenPrice());
                    vo.setPreClosePrice(marketLogPrice.getPreClosePrice());
                    found = true;
                    break;
                }
            }
            if (!found) {
                vo.setOpenPrice(BigDecimal.ZERO);
                vo.setPreClosePrice(BigDecimal.ZERO);
            }
            return vo;
        }).toList();
    }

    @Override
    public List<StockBusiness> getStockBusiness() {
        return stockBusinessMapper.selectAll();
    }
}
